﻿using System;

namespace Snake.FSM
{
    public class FsmCondition<TOwner>
    {
        private Func<TOwner, bool> _conditionHandle;

        protected FsmCondition()
        {
        }

        public FsmCondition(Func<TOwner, bool> handle)
        {
            BindCondition(handle);
        }

        public void BindCondition(Func<TOwner, bool> handle)
        {
            _conditionHandle = handle;
        }

        public virtual bool Condition(TOwner owner)
        {
            return _conditionHandle != null && _conditionHandle.Invoke(owner);
        }

        public static FsmCondition<TOwner> operator &(FsmCondition<TOwner> con1, FsmCondition<TOwner> con2)
        {
            return new AndCondition<TOwner>(con1, con2);
        }

        public static FsmCondition<TOwner> operator |(FsmCondition<TOwner> con1, FsmCondition<TOwner> con2)
        {
            return new OrCondition<TOwner>(con1, con2);
        }

        public static FsmCondition<TOwner> operator !(FsmCondition<TOwner> con)
        {
            return new NotCondition<TOwner>(con);
        }
    }

    public class FsmCondition<TOwner, TOther> : FsmCondition<TOwner>
    {
        private Func<TOwner, TOther, bool> _condition;
        private TOther _mValue;

        public FsmCondition()
        {
        }

        public FsmCondition(Func<TOwner, TOther, bool> condition, TOther value)
        {
            BindCondition(condition, value);
        }

        public void BindCondition(Func<TOwner, TOther, bool> condition, TOther value)
        {
            _condition = condition;
            _mValue = value;
        }

        public override bool Condition(TOwner owner)
        {
            return _condition != null && _condition(owner, _mValue);
        }
    }
}